package org.junior.base.advice;

import org.junior.base.domain.vo.ResponseResultVo;
import org.junior.base.enums.ErrorHttpCodeEnum;
import org.junior.base.exception.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
* @Description: 全局异常处理
* @Author: Junior
* @Date: 2024/7/22
*/
@RestControllerAdvice
public class GlobalExceptionAdvice {

    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionAdvice.class);

    public static final String EXCEPTION_PREFIX = "[全局接口异常捕获服务]---> 捕获到异常: {}";

    /**
    * 自定义业务异常
    * @param e:  异常
    * @return org.junior.base.domain.vo.ResponseResultVo<?>
    * @Author: Junior
    * @Date: 2024/7/22
    */
    @ExceptionHandler(BusinessException.class)
    public ResponseResultVo<?> handleBusinessException(BusinessException e) {
        log.error(EXCEPTION_PREFIX, e.toString(), e);
        if (e.getErrorCode() == null) {
            // 如何 code 不存在, 则使用默认错误 code
            return ResponseResultVo.fail(e.getMessage());
        }
        return ResponseResultVo.fail(e.getErrorCode(), e.getErrorMsg());
    }

    /**
    * 数学计算错误
    * @param e:  e
    * @return org.junior.base.domain.vo.ResponseResultVo<?>
    * @Author: Junior
    * @Date: 2024/8/7
    */
    @ExceptionHandler(ArithmeticException.class)
    public ResponseResultVo<?> handleArithmeticException(ArithmeticException e) {
        log.error(EXCEPTION_PREFIX, e.toString(), e);
        return ResponseResultVo.fail(ErrorHttpCodeEnum.ARITHMETIC_ERROR);
    }

    /**
    * 请求方式不支持
    * @return org.junior.base.domain.vo.ResponseResultVo<?>
    * @Author: Junior
    * @Date: 2024/7/22
    */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ResponseResultVo<?> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e) {
        log.error(EXCEPTION_PREFIX, e.toString(), e);
        return ResponseResultVo.fail(ErrorHttpCodeEnum.REQUEST_METHOD_ERROR);
    }

    /**
     * 参数验证失败异常
     *
     * @return org.junior.base.domain.vo.ResponseResultVo<?>
     * @Author: Junior
     * @Date: 2024/7/22
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseResultVo<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error(EXCEPTION_PREFIX, e.toString(), e);
        return ResponseResultVo.fail(ErrorHttpCodeEnum.PARAMETER_ERROR);
    }

    /**
     * sql 语句异常
     *
     * @return org.junior.base.domain.vo.ResponseResultVo<?>
     * @Author: Junior
     * @Date: 2024/7/22
     */
    @ExceptionHandler(BadSqlGrammarException.class)
    public ResponseResultVo<?> handleBadSqlGrammarException(BadSqlGrammarException e) {
        log.error(EXCEPTION_PREFIX, e.toString(), e);
        return ResponseResultVo.fail(ErrorHttpCodeEnum.DATABASE_ERROR);
    }

    /**
     * 违反数据库完整性约束异常
     *
     * @return org.junior.base.domain.vo.ResponseResultVo<?>
     * @Author: Junior
     * @Date: 2024/7/22
     */
    @ExceptionHandler(DataIntegrityViolationException.class)
    public ResponseResultVo<?> handleDataIntegrityViolationException(DataIntegrityViolationException e) {
        log.error(EXCEPTION_PREFIX, e.toString(), e);
        return ResponseResultVo.fail(ErrorHttpCodeEnum.DATABASE_ERROR);
    }

    /**
     * 未分类的SQL异常
     *
     * @return org.junior.base.domain.vo.ResponseResultVo<?>
     * @Author: Junior
     * @Date: 2024/7/22
     */
    @ExceptionHandler(UncategorizedSQLException.class)
    public ResponseResultVo<?> handleUncategorizedSqlException(UncategorizedSQLException e) {
        log.error(EXCEPTION_PREFIX, e.toString(), e);
        return ResponseResultVo.fail(ErrorHttpCodeEnum.DATABASE_ERROR);
    }

    /**
     * 未知的运行时异常
     *
     * @return org.junior.base.domain.vo.ResponseResultVo<?>
     * @Author: Junior
     * @Date: 2024/7/22
     */
    @ExceptionHandler(RuntimeException.class)
    public ResponseResultVo<?> handleRuntimeException(RuntimeException e) {
        log.error(EXCEPTION_PREFIX, e.toString(), e);
        return ResponseResultVo.fail(ErrorHttpCodeEnum.RUNTIME_ERROR);
    }

}
